/******************************************************************************
 * FileName:    gwin_misc_api.c
 * Desc:        杂项接口
 *
 *
 * Author:      Lin
 * Notes:
 *
 ******************************************************************************/

/*-------------------------- Includes ---------------------------------------*/
#include "gwin_misc_api.h"


/*-------------------------- Macro Definitions ------------------------------*/

/*-------------------------- Type Declarations ------------------------------*/

/*-------------------------- Global Variables -------------------------------*/

/*-------------------------- Local Variables --------------------------------*/

/*-------------------------- Functions Declarations -------------------------*/

/*-------------------------- Functions Definitions --------------------------*/
/**
 * @brief 数据校验
 */
uint8_t _check_sum(uint8_t *data, uint16_t len)
{
    uint8_t check_sum = 0;

    for (uint16_t i = 0; i < len; i++)
    {
        check_sum += data[i];
    }

    return check_sum;
}

/**
 * @brief 十六进制字符转数值
 */
static uint8_t hex_ch_to_num(uint8_t ch)
{
    uint8_t num = 0;

    if (ch >= '0' && ch <= '9')
    {
        num = ch - '0';
    }
    else if (ch >= 'a' && ch <= 'f' )
    {
        num = ch - 'a' + 10;
    }
    else if (ch >= 'A' && ch <= 'F')
    {
        num = ch - 'A' + 10;
    }

    return num;
}

/**
 * @brief 十六进制字符串转十六进制
 */
void hex_str_to_hex(const uint8_t *hex_str, uint32_t hex_str_len, uint8_t *hex, uint32_t hex_len)
{
    if (NULL == hex_str || NULL == hex) return;

    uint32_t len = MIN(hex_str_len / 2, hex_len);
    for (uint32_t i = 0; i < len; i++)
    {
        hex[i] = (hex_ch_to_num(hex_str[0]) << 4) + hex_ch_to_num(hex_str[1]);
        hex_str += 2;
    }
}

/**
 * @brief 十六进制转十六进制字符串
 */
void hex_to_hex_str(const uint8_t *hex, uint32_t hex_len, uint8_t *hex_str, uint32_t hex_str_len)
{
    if (NULL == hex_str || NULL == hex) return;

    memset(hex_str, 0x00, hex_str_len);
    for (uint32_t i = 0; i < hex_len; i++)
    {
        if (i * 2 > hex_str_len)
        {
            break;
        }
        sprintf((char*)hex_str + i * 2, "%02x", hex[i]);
    }
}


/**
 * @brief 交互两个数
 */
static void swap(uint16_t *a, uint16_t *b)
{
    uint16_t c = *a;
    *a = *b;
    *b = c;
}

/**
 * @brief 选择排序
 */
void select_sort(uint16_t *data, uint16_t len)
{
    uint16_t left = 0;
    uint16_t right = len - 1;
    while (left < right)
    {
        uint16_t min_i = left;
        uint16_t max_i = left;
        for (uint16_t i = left; i <= right; i++)
        {
            if (data[i] < data[min_i])
            {
                min_i = i;
            }
            if (data[i] > data[max_i])
            {
                max_i = i;
            }
        }
        swap(&data[min_i], &data[left]);
        if (max_i == left)
        {
            max_i = min_i;
        }
        swap(&data[max_i], &data[right]);
        left++;
        right--;
    }
}

/**
 * @brief 选择性平均值
 */
uint32_t average_pos(uint16_t *data, uint16_t len, uint16_t pos)
{
    uint32_t sum = 0;
    for (uint16_t i = 0; i < len; i++)
    {
        sum += data[pos + i];
    }
    return (sum / len);
}

/**
 * @brief 二分查找
 */
int binary_search(uint32_t *data, uint32_t len, uint32_t target)
{
    uint32_t left = 0;
    uint32_t right = len - 1;
    uint32_t mid = 0;

    while (left <= right)
    {
        mid = left + (right - left) / 2;
        if (data[mid] < target)
        {
            left = mid + 1;
        }
        else if (target < data[mid])
        {
            right = mid - 1;
        }
        else
        {
            return mid;
        }
    }

    return -1;
}
/**
 * @brief 二分查找
 *          二分查找法：分析数据0000001111，查找首次为1的位置
 */
int binary_search_01(uint32_t *data, uint32_t len)
{
    uint32_t left = 0;
    uint32_t right = len - 1;
    uint32_t mid = 0;
    uint32_t next = 0;

    while (left <= right)
    {
        mid = left + (right - left) / 2;
        next = MIN(mid + 1, right);
        if (!data[mid] && data[next])
        {
            return mid;
        }
        else
        {
            if (data[mid] == 0)
            {
                left = mid + 1;
            }
            else
            {
                right = mid - 1;
            }
        }
    }

    return -1;
}


#include "gwin_board.h"
#include "gwin_general_clock.h"
/**
 * @brief 获取 utc时间
 */
static uint32_t utc_timestamp = 0;
uint32_t system_get_utc(void)
{
    return (utc_timestamp + system_tick_ms() / 1000);
}
/**
 * @brief 设置 utc时间
 */
void system_set_utc(uint32_t utc_time)
{
    utc_timestamp = utc_time - system_tick_ms() / 1000;
}


/*-------------------------- END OF FILE ------------------------------------*/

